{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# [动态图](https://www.paddlepaddle.org.cn/documentation/docs/zh/practices/quick_start/dynamic_graph.html)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/usr/lib/python3/dist-packages/urllib3/util/selectors.py:14: DeprecationWarning: Using or importing the ABCs from 'collections' instead of from 'collections.abc' is deprecated since Python 3.3, and in 3.10 it will stop working\n",
      "  from collections import namedtuple, Mapping\n",
      "/usr/lib/python3/dist-packages/urllib3/_collections.py:2: DeprecationWarning: Using or importing the ABCs from 'collections' instead of from 'collections.abc' is deprecated since Python 3.3, and in 3.10 it will stop working\n",
      "  from collections import Mapping, MutableMapping\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "2.1.0\n"
     ]
    }
   ],
   "source": [
    "import paddle\n",
    "import paddle.nn.functional as F\n",
    "import numpy as np\n",
    "\n",
    "print(paddle.__version__)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/usr/local/lib/python3.8/dist-packages/ipykernel/ipkernel.py:283: DeprecationWarning: `should_run_async` will not call `transform_cell` automatically in the future. Please pass the result to `transformed_cell` argument and any exception that happen during thetransform in `preprocessing_exc_tuple` in IPython 7.17 and above.\n",
      "  and should_run_async(code)\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Tensor(shape=[4, 2], dtype=float32, place=CUDAPlace(0), stop_gradient=True,\n",
      "       [[-0.15331772,  0.08634651],\n",
      "        [-0.70562023, -0.57778221],\n",
      "        [-0.80252743, -0.97575682],\n",
      "        [-1.71723878, -1.29718602]])\n",
      "Tensor(shape=[2], dtype=float32, place=CUDAPlace(0), stop_gradient=True,\n",
      "       [1., 2.])\n",
      "Tensor(shape=[4, 2], dtype=float32, place=CUDAPlace(0), stop_gradient=True,\n",
      "       [[ 0.84668231,  2.08634663],\n",
      "        [ 0.29437977,  1.42221785],\n",
      "        [ 0.19747257,  1.02424312],\n",
      "        [-0.71723878,  0.70281398]])\n",
      "Tensor(shape=[4], dtype=float32, place=CUDAPlace(0), stop_gradient=True,\n",
      "       [ 0.01940918, -1.86083984, -2.75390625, -4.31054688])\n"
     ]
    }
   ],
   "source": [
    "a = paddle.randn([4, 2])\n",
    "b = paddle.arange(1, 3, dtype=\"float32\")\n",
    "\n",
    "print(a)\n",
    "print(b)\n",
    "\n",
    "c = a + b\n",
    "print(c)\n",
    "\n",
    "d = paddle.matmul(a, b)\n",
    "print(d)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0 -> [-3 -4 -5]\n",
      "1 -> [-3 -3 -3]\n",
      "2 +> [ 5  9 15]\n",
      "3 +> [ 5 13 33]\n",
      "4 -> [-3 11 75]\n",
      "5 -> [ -3  27 237]\n",
      "6 -> [ -3  59 723]\n",
      "7 +> [   5  133 2193]\n",
      "8 +> [   5  261 6567]\n",
      "9 -> [   -3   507 19677]\n"
     ]
    }
   ],
   "source": [
    "a = paddle.to_tensor(np.array([1, 2, 3]))\n",
    "b = paddle.to_tensor(np.array([4, 5, 6]))\n",
    "\n",
    "for i in range(10):\n",
    "    r = paddle.rand([1])\n",
    "    if r > 0.5:\n",
    "        c = paddle.pow(a, i) + b\n",
    "        print(\"{} +> {}\".format(i, c.numpy()))\n",
    "    else:\n",
    "        c = paddle.pow(a, i) - b\n",
    "        print(\"{} -> {}\".format(i, c.numpy()))\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "class MyModel(paddle.nn.Layer):\n",
    "    def __init__(self, input_size, hidden_size):\n",
    "        super().__init__()\n",
    "        self.linear1 = paddle.nn.Linear(input_size, hidden_size)\n",
    "        self.linear2 = paddle.nn.Linear(hidden_size, hidden_size)\n",
    "        self.linear3 = paddle.nn.Linear(hidden_size, 1)\n",
    "\n",
    "    def forward(self, inputs):\n",
    "        x = self.linear1(inputs)\n",
    "        x = F.relu(x)\n",
    "\n",
    "        if (\n",
    "            paddle.rand(\n",
    "                [\n",
    "                    1,\n",
    "                ]\n",
    "            )\n",
    "            > 0.5\n",
    "        ):\n",
    "            x = self.linear2(x)\n",
    "            x = F.relu(x)\n",
    "\n",
    "        x = self.linear3(x)\n",
    "\n",
    "        return x\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0 [1.1634886]\n",
      "200 [0.8433169]\n",
      "400 [0.5744595]\n",
      "600 [0.33925566]\n",
      "800 [0.20290668]\n",
      "1000 [0.03108981]\n",
      "1200 [0.0147598]\n",
      "1400 [0.03148366]\n",
      "1600 [0.01933179]\n",
      "1800 [0.01571309]\n",
      "2000 [0.00690854]\n",
      "2200 [0.00395913]\n",
      "2400 [0.00111237]\n",
      "2600 [0.00119752]\n",
      "2800 [0.00211889]\n"
     ]
    }
   ],
   "source": [
    "total_data, batch_size, input_size, hidden_size = 1000, 64, 128, 256\n",
    "\n",
    "x_data = np.random.randn(total_data, input_size).astype(np.float32)\n",
    "y_data = np.random.randn(total_data, 1).astype(np.float32)\n",
    "\n",
    "model = MyModel(input_size, hidden_size)\n",
    "\n",
    "loss_fn = paddle.nn.MSELoss(reduction=\"mean\")\n",
    "optimizer = paddle.optimizer.SGD(\n",
    "    learning_rate=0.01, parameters=model.parameters()\n",
    ")\n",
    "\n",
    "for t in range(200 * (total_data // batch_size)):\n",
    "    idx = np.random.choice(total_data, batch_size, replace=False)\n",
    "    x = paddle.to_tensor(x_data[idx, :])\n",
    "    y = paddle.to_tensor(y_data[idx, :])\n",
    "    y_pred = model(x)\n",
    "\n",
    "    loss = loss_fn(y_pred, y)\n",
    "    if t % 200 == 0:\n",
    "        print(t, loss.numpy())\n",
    "\n",
    "    loss.backward()\n",
    "    optimizer.step()\n",
    "    optimizer.clear_grad()\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "step: 0, loss: [0.33422834]\n",
      "step: 1, loss: [0.30259538]\n",
      "step: 2, loss: [0.28444836]\n",
      "step: 3, loss: [0.26674908]\n",
      "step: 4, loss: [0.24389827]\n",
      "step: 5, loss: [0.21575621]\n",
      "step: 6, loss: [0.18521091]\n",
      "step: 7, loss: [0.15673597]\n",
      "step: 8, loss: [0.13444695]\n",
      "step: 9, loss: [0.11906408]\n"
     ]
    }
   ],
   "source": [
    "inputs = paddle.rand((256, 64))\n",
    "\n",
    "linear = paddle.nn.Linear(64, 8, bias_attr=False)\n",
    "loss_fn = paddle.nn.MSELoss()\n",
    "optimizer = paddle.optimizer.Adam(0.01, parameters=linear.parameters())\n",
    "\n",
    "for i in range(10):\n",
    "    hidden = linear(inputs)\n",
    "    # weight from input to hidden is shared with the linear mapping from hidden to output\n",
    "    outputs = paddle.matmul(hidden, linear.weight, transpose_y=True)\n",
    "    loss = loss_fn(outputs, inputs)\n",
    "    loss.backward()\n",
    "    print(\"step: {}, loss: {}\".format(i, loss.numpy()))\n",
    "    optimizer.step()\n",
    "    optimizer.clear_grad()\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.10"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
